// 实现这个项目的构建任务

const { src, dest, series, parallel, watch } = require('gulp');
const loadPlugins = require('gulp-load-plugins');
const browserSync = require('browser-sync');
const del = require('del');
const exec = require('child_process').exec

const plugins = loadPlugins();

const bs = browserSync.create();

const data = require('./data');

console.log(process.argv, data)

const style = () => {
    return src('src/assets/styles/*.scss', { base: 'src' })
        .pipe(plugins.sass({
            outputStyle: 'expanded'
        }))
        .pipe(dest('temp'))
}

const script = () => {
    return src('src/assets/scripts/*.js', { base: 'src' })
        .pipe(plugins.babel({
            presets: ['@babel/preset-env']
        }))
        .pipe(dest('temp'))
}

const page = () => {
    return src('src/*.html', { base: 'src' })
        .pipe(plugins.swig({ data, defaults: { cache: false } })) // 关闭缓存防止修改不实时生效
        .pipe(dest('temp'))
}

const image = () => {
    return src('src/assets/images/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest('dist'))
}

const font = () => {
    return src('src/assets/fonts/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest('dist'))
}

const extra = () => {
    return src('public/**', { base: 'public' })        
        .pipe(dest('dist'))
}

const clean = () => {
    return del(['dist', 'temp'])
}

const compile = parallel(style, script, page)



const useref = () => {
    if(process.argv.includes('--production') || process.argv.includes('--prod')) {
        return src('temp/*.html', { base: 'temp' })
            .pipe(plugins.useref({
                searchPath: ['temp', '.']
            }))
            .pipe(plugins.if(/\.js$/, plugins.uglify()))
            .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
            .pipe(plugins.if(/\.html$/, plugins.htmlmin({
                collapseWhitespace: true,
                minifyCSS: true,
                minifyJS: true,
            })))
            .pipe(dest('dist'))
    } else {
        return src('temp/*.html', { base: 'temp' })
            .pipe(plugins.useref({
                searchPath: ['temp', '.']
            }))
            .pipe(dest('dist'))
    }
}

const build = series(clean, parallel(series(compile, useref), image, font, extra))

const serve = series(compile, () => {
    watch('src/assets/styles/*.scss', style)
    watch('src/assets/scripts/*.js', script)
    watch('src/*.html', page)
    watch([
        'src/assets/images/**',
        'src/assets/fonts/**',
        'public/**',
    ], bs.reload)

    let port = 2080;
    const idx = process.argv.indexOf('--port')
    if(idx !== -1) {
        try {
            if(!isNaN(Number(process.argv[idx + 1]))){
                port = Number(process.argv[idx + 1])
            }
        } catch(e) {}
    }

    bs.init({
        notify: false,
        open: process.argv.includes('--open'),
        files: 'temp/**',
        port,
        server: {
            baseDir: ['temp', 'src', 'public'],
            routes: {
                '/node_modules': './node_modules'
            }
        }
    })
})

const start = series(build, () => {
    watch('src/assets/styles/*.scss', series(style, useref))
    watch('src/assets/scripts/*.js', series(script, useref))
    watch('src/**/*.html', series(page, useref))
    watch('src/assets/images/**', image)
    watch('src/assets/fonts/**', font)
    watch('public/**', extra)

    let port = 2080;
    const idx = process.argv.indexOf('--port')
    if(idx !== -1) {
        try {
            if(!isNaN(Number(process.argv[idx + 1]))){
                port = Number(process.argv[idx + 1])
            }
        } catch(e) {}
    }

    bs.init({
        notify: false,
        open: process.argv.includes('--open'),
        files: 'dist/**',
        port,
        server: {
            baseDir: ['dist'],
            routes: {
                '/node_modules': './node_modules'
            }
        }
    })
})

const eslint = () => {
    return src('src/assets/scripts/*.js')
        .pipe(plugins.eslint())
}

const sasslint = () => {
    return src('src/assets/styles/*.scss')
        .pipe(plugins.sassLint())
}

const lint = series(eslint, sasslint)


const pull = done => {
    const cmd = 'git pull'
    exec(cmd, function(error, stdout, stderr) {
        done(error)
    })
}

const checkout = done => {
    let branch = 'gh-pages'
    const idx = process.argv.indexOf('--branch')
    if(idx !== -1) {
        try {
            branch = process.argv[idx + 1]
        } catch(e) {}
    }
    const cmd = `git checkout ${branch}`
    exec(cmd, function(error, stdout, stderr) {
        done(error)
    })
}

const add = done => {
    const cmd = 'git add dist'
    exec(cmd, function(error, stdout, stderr) {
        done(error)
    })
}

const commit = done => {
    const cmd = 'git commit -m "deploy dist"'
    exec(cmd, function(error, stdout, stderr) {
        done(error)
    })
}

const push = done => {
    const cmd = 'git push'
    exec(cmd, function(error, stdout, stderr) {
        done(error)
    })
}

const deploy = series(build, pull, checkout, add, commit, push)

module.exports = {
    serve,
    start,
    lint,
    clean,
    build,
    compile,    
    deploy,
}